home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Business Shareware
/
Business Shareware.iso
/
start
/
gfxapps
/
hv12
/
src
/
viewer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-22
|
57KB
|
2,022 lines
/* CONDITIONAL COMPILATION FLAGS */
#define BRUCE 1
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <sys/time.h>
struct timezone {int hell1; int hell2;};
#include "mypow.h"
#include "jinclude.h"
#include "hicolor.h"
#include "viewer.h"
#include "dither.h"
#include "pc.h"
#include "dir.h"
#include "gppconio.h"
#include "grx.h"
#include "grdriver.h"
/*
* Include file for declaring JPEG data structures.
* This file also includes some system headers like <stdio.h>;
* if you prefer, you can include "jconfig.h" and "jpegdata.h" instead.
*/
void targa_input_init (compress_info_ptr cinfo);
/* GLOBALS */
#ifdef VIEW_DEBUG
int debugrow;
#endif
ulong *Buffer0, *Buffer1, *Buffer2; /* buffer to hold one row of pixels */
BYTE ColorLUT[257];
BYTE ColorLUT256[257];
WORD *DispBuf;
char *DispBuf256;
int NewTotal; /* */
int XOffset, YOffset;
int filerow, endrow, scrrow;
int BytesPerPixel;
long bytesPerRow;
ulong lOffset;
ulong Ytotal;
ulong Yratio, Xratio, InvYratio, InvXratio;
int width; /* number of pixels to display in a row */
int height;
int sameaspectF;
int scaleF, interpF, isbottomupF, ditherF, GinterpF, hicolorF, nohicolor, twopassF,
blocksmoothF, pixelsmoothF, debugF,old_driversF,timeF,slideF;
int F1024, F800, F640, hi800F, hi640F;
int slidedelay;
IMAGE_FORMATS FormatFlag = FMT_JFIF; /* image file format */
double Gamma; /* exponent for contrast stretch */
DCtrlType DitherCtrl;
char PB[512];
Files moh_files[MAXFILES];
int totalfiles = 0;
GR_DRIVER_MODE_ENTRY far *ttab, *gtab;
extern JSAMPARRAY gifcolormap;
/*
* <setjmp.h> is used for the optional error recovery mechanism shown in
* the second part of the example.
*/
#include <setjmp.h>
/******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/
/* This half of the example shows how to read data from the JPEG decompressor.
* It's a little more refined than the above in that we show how to do your
* own error recovery. If you don't care about that, you don't need these
* next two routines.
*/
/*
* These routines replace the default trace/error routines included with the
* JPEG code. The example trace_message routine shown here is actually the
* same as the standard one, but you could modify it if you don't want messages
* sent to stderr. The example error_exit routine is set up to return
* control to read_JPEG_file() rather than calling exit(). You can use the
* same routines for both compression and decompression error recovery.
*/
/* These static variables are needed by the error routines. */
static jmp_buf setjmp_buffer; /* for return to caller */
static external_methods_ptr emethods; /* needed for access to message_parm */
/* This routine is used for any and all trace, debug, or error printouts
* from the JPEG code. The parameter is a printf format string; up to 8
* integer data values for the format string have been stored in the
* message_parm[] field of the external_methods struct.
*/
METHODDEF void
trace_message (const char *msgtext)
{
fprintf (stderr, msgtext,
emethods->message_parm[0], emethods->message_parm[1],
emethods->message_parm[2], emethods->message_parm[3],
emethods->message_parm[4], emethods->message_parm[5],
emethods->message_parm[6], emethods->message_parm[7]);
fprintf (stderr, "\n"); /* there is no \n in the format string! */
}
/*
* The error_exit() routine should not return to its caller. The default
* routine calls exit(), but here we assume that we want to return to
* read_JPEG_data, which has set up a setjmp context for the purpose.
* You should make sure that the free_all method is called, either within
* error_exit or after the return to the outer-level routine.
*/
METHODDEF void
error_exit (const char *msgtext)
{
trace_message (msgtext); /* report the error message */
(*emethods->free_all) (); /* clean up memory allocation & temp files */
longjmp (setjmp_buffer, 1); /* return control to outer routine */
}
/*
* To accept the image data from decompression, you must define four routines
* output_init, put_color_map, put_pixel_rows, and output_term.
*
* You must understand the distinction between full color output mode
* (N independent color components) and colormapped output mode (a single
* output component representing an index into a color map). You should use
* colormapped mode to write to a colormapped display screen or output file.
* Colormapped mode is also useful for reducing grayscale output to a small
* number of gray levels: when using the 1-pass quantizer on grayscale data,
* the colormap entries will be evenly spaced from 0 to MAX_JSAMPLE, so you
* can regard the indexes are directly representing gray levels at reduced
* precision. In any other case, you should not depend on the colormap
* entries having any particular order.
* To get colormapped output, set cinfo->quantize_colors to TRUE and set
* cinfo->desired_number_of_colors to the maximum number of entries in the
* colormap. This can be done either in your main routine or in
* d_ui_method_selection. For grayscale quantization, also set
* cinfo->two_pass_quantize to FALSE to ensure the 1-pass quantizer is used
* (presently this is the default, but it may not be so in the future).
*
* The output file writing modules (jwrppm.c, jwrgif.c, jwrtarga.c, etc) may be
* useful examples of what these routines should actually do, although each of
* them is encrusted with a lot of specialized code for its own file format.
*/
#ifdef OLD_CODE
void
MakeColorLUT (
BYTE * pLut, /* array to hold LUT */
BYTE minIn, /* minimum input intensity */
BYTE maxIn, /* maximum input intensity */
BYTE minOut, /* minimum output intensity */
BYTE maxOut, /* maximum output intensity */
double gamma /* exponent of stretch */
)
{
int index; /* LUT index */
double scale; /* scale factor (K) */
double lutVal; /* LUT value */
scale = (maxOut - minOut) / pow (maxIn - minIn, gamma);
for (index = minIn; index <= maxIn; index++)
{
lutVal = minOut + scale * pow (index - minIn, gamma);
*pLut++ = (BYTE) (lutVal + 0.5);
}
}
#endif
void
MakeColorLUT (
BYTE * pLut, /* array to hold LUT */
BYTE maxOut,
double gamma /* exponent of stretch */
)
{
int index; /* LUT index */
long intgamma;
intgamma=(long) ((1L << PowInfBase)*gamma);
/*
scale = (maxOut - minOut) / pow (maxIn - minIn, gamma);
*/
*pLut++ = 0;
for (index = 1; index <= 255; index++)
{
*pLut++ = (BYTE) ((maxOut*mypow(index,intgamma)+(1L << (2*PowInfBase-1)))
>> (2*PowInfBase));
}
}
METHODDEF void
output_init (decompress_info_ptr cinfo)
/* This routine should do any setup required */
{
/* This routine can initialize for output based on the data passed in
cinfo. Useful fields include: image_width, image_height Pretty
obvious, I hope. data_precision bits per pixel value;
typically 8. out_color_space output colorspace
previously requested color_out_comps number of
color components in same final_out_comps number of
components actually output final_out_comps is 1 if quantize_colors is
true, else it is equal to color_out_comps.
If you have requested color quantization, the colormap is NOT yet set. You
may wish to defer output initialization until put_color_map is called. */
int mode = 0x30;
int w, h;
ulong *b0, *b1, *b2;
int i, j, k;
int numcolors, scrwidth, scrheight;
if (hicolorF)
{
numcolors = 32768;
BytesPerPixel = 2;
scrwidth = 640;
scrheight = 480;
if ((cinfo->image_width > 640 || cinfo->image_height > 480) && hi800F)
{
scrwidth = 800;
scrheight = 600;
}
}
else
{
numcolors = 256;
BytesPerPixel = 1;
scrwidth = 640;
scrheight = 480;
if ((cinfo->image_width > 640 || cinfo->image_height > 480) && F800)
{
scrwidth = 800;
scrheight = 600;
}
if ((cinfo->image_width > 800 || cinfo->image_height > 600) && F1024)
{
scrwidth = 1024;
scrheight = 768;
}
}
bytesPerRow = scrwidth * BytesPerPixel;
interpF = GinterpF;
NewTotal = 0;
Ytotal = 0;
XOffset = YOffset = 0;
scrrow = 0;
filerow = 0;
Xratio = Yratio = (1L << InflateBase);
InvXratio = InvYratio = (1L << InflateBase);
w = cinfo->image_width;
h = cinfo->image_height;
if (w > scrwidth)
{
Xratio = (w << InflateBase) / (scrwidth);
InvXratio = (scrwidth << InflateBase) / w;
}
if (h > scrheight)
{
Yratio = (h << InflateBase) / (scrheight);
InvYratio = (scrheight << InflateBase) / h;
}
if (sameaspectF)
{
if (Yratio > Xratio)
{
Xratio = Yratio;
InvXratio = InvYratio;
}
else
{
Yratio = Xratio;
InvYratio = InvXratio;
}
}
if (!scaleF)
{
Xratio = Yratio = (1L << InflateBase);
InvXratio = InvYratio = (1L << InflateBase);
}
w = cinfo->image_width * InvXratio;
h = cinfo->image_height * InvYratio;
if (w % (1L << InflateBase))
{
w = w >> InflateBase;
w++;
}
else
w = w >> InflateBase;
if (h % (1L << InflateBase))
{
h = h >> InflateBase;
h++;
}
else
h = h >> InflateBase;
width = (cinfo->image_width * InvXratio) >> InflateBase;
height = (cinfo->image_width * InvYratio) >> InflateBase;
if (w <= scrwidth)
XOffset = (scrwidth - w) / 2;
if (h <= scrheight)
YOffset = (scrheight - h) / 2;
lOffset = 0xd0200000 + (ulong) YOffset *bytesPerRow + XOffset * BytesPerPixel;
endrow = Yratio >> InflateBase;
if (Xratio == (1L << InflateBase) && Yratio == (1L << InflateBase))
interpF = 0;
if (cinfo->total_passes == IS_BOTTOM_UP)
{ /* ### kludge for bottom up
targa files */
lOffset += h * bytesPerRow;
bytesPerRow = -bytesPerRow;
}
b0 = Buffer0 = (ulong *) jget_small (sizeof (ulong) * cinfo->image_width);
b1 = Buffer1 = (ulong *) jget_small (sizeof (ulong) * cinfo->image_width);
b2 = Buffer2 = (ulong *) jget_small (sizeof (ulong) * cinfo->image_width);
for (i = 0; i < cinfo->image_width; i++)
*b0++ = *b1++ = *b2++ = 0;
DispBuf = (WORD *) jget_small (sizeof (WORD) * cinfo->image_width);
DispBuf256 = (char *) jget_small (sizeof (char) * cinfo->image_width);
if (ditherF)
if (interpF)
DitherInit (0, 255, 0, 31, width, &DitherCtrl);
else
DitherInit (0, 255, 0, 31, cinfo->image_width, &DitherCtrl);
if (debugF)
{
printf ("image : %ld x %ld \n", cinfo->image_width, cinfo->image_height);
printf ("screen %dx%d\n", scrwidth, scrheight);
printf ("Xratio: %ld Yratio: %ld\n", Xratio, Yratio);
printf ("InvXratio: %ld InvYratio: %ld\n", InvXratio, InvYratio);
printf ("screen width %d\n", width);
if (interpF)
printf ("interpolating output\n");
else
printf ("Not interpolating output\n");
if (ditherF)
printf ("dithering output\n");
else
printf ("Not dithering output\n");
printf ("out color space: %d\n", (int) cinfo->out_color_space);
if (getch () == 'q')
exit (0);
printf ("ok.\n");
}
#ifdef VIEW_DEBUG
if (debugF) debugrow=0;
else {
#endif
if (old_driversF)
GrSetMode (GR_width_height_graphics,
scrwidth, scrheight);
else
GrSetMode (GR_width_height_color_graphics,
scrwidth, scrheight, numcolors);
/*
SetVideoMode(mode);
*/
/* my Tseng manual says we should be in 256 */
/*
SetHicolorMode(mode);
*/
/* color mode before switching to hicolor */
#ifdef VIEW_DEBUG
}
#endif
}
/*
* This routine is called if and only if you have set cinfo->quantize_colors
* to TRUE. It is given the selected colormap and can complete any required
* initialization. This call will occur after output_init and before any
* calls to put_pixel_rows. Note that the colormap pointer is also placed
* in a cinfo field, whence it can be used by put_pixel_rows or output_term.
* num_colors will be less than or equal to desired_number_of_colors.
*
* The colormap data is supplied as a 2-D array of JSAMPLEs, indexed as
* JSAMPLE colormap[component][indexvalue]
* where component runs from 0 to cinfo->color_out_comps-1, and indexvalue
* runs from 0 to num_colors-1. Note that this is actually an array of
* pointers to arrays rather than a true 2D array, since C does not support
* variable-size multidimensional arrays.
* JSAMPLE is typically typedef'd as "unsigned char". If you want your code
* to be as portable as the JPEG code proper, you should always access JSAMPLE
* values with the GETJSAMPLE() macro, which will do the right thing if the
* machine has only signed chars.
*/
METHODDEF void
put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
/* Write the color map */
{
int i;
JSAMPROW ptr0, ptr1, ptr2;
/* You need not provide this routine if you always set
cinfo->quantize_colors FALSE; but a safer practice is to provide it and
have it just print an error message, like this: */
/*
fprintf(stderr, "put_color_map called: there's a bug here somewhere!\n");
*/
#ifdef VIEW_DEBUG
if (debugF) printf("put_color_map called\n");
else {
#endif
ptr0 = colormap[0];
if (cinfo->out_color_space == CS_RGB)
{
ptr1 = colormap[1];
ptr2 = colormap[2];
}
else
ptr1 = ptr2 = ptr0;
for (i = 0; i < num_colors; i++)
GrSetColor (i, ColorLUT256[*(ptr0++)],
ColorLUT256[*(ptr1++)], ColorLUT256[*(ptr2++)]);
#ifdef VIEW_DEBUG
}
#endif
}
/*
* This function is called repeatedly, with a few more rows of pixels supplied
* on each call. With the current JPEG code, some multiple of 8 rows will be
* passed on each call except the last, but it is extremely bad form to depend
* on this. You CAN assume num_rows > 0.
* The data is supplied in top-to-bottom row order (the standard order within
* a JPEG file). If you cannot readily use the data in that order, you'll
* need an intermediate array to hold the image. See jwrrle.c for an example
* of outputting data in bottom-to-top order.
*
* The data is supplied as a 3-D array of JSAMPLEs, indexed as
* JSAMPLE pixel_data[component][row][column]
* where component runs from 0 to cinfo->final_out_comps-1, row runs from 0 to
* num_rows-1, and column runs from 0 to cinfo->image_width-1 (column 0 is
* left edge of image). Note that this is actually an array of pointers to
* pointers to arrays rather than a true 3D array, since C does not support
* variable-size multidimensional arrays.
* JSAMPLE is typically typedef'd as "unsigned char". If you want your code
* to be as portable as the JPEG code proper, you should always access JSAMPLE
* values with the GETJSAMPLE() macro, which will do the right thing if the
* machine has only signed chars.
*
* If quantize_colors is true, then there is only one component, and its values
* are indexes into the previously supplied colormap. Otherwise the values
* are actual data in your selected output colorspace.
*/
#define SRED GETJSAMPLE(*ptr0)
#define SGREEN GETJSAMPLE(*ptr1)
#define SBLUE GETJSAMPLE(*ptr2)
METHODDEF void
put_pixel_rows256 (decompress_info_ptr cinfo, int num_rows,
JSAMPIMAGE pixel_data)
{
int col, row;
JSAMPROW ptr0;
#ifdef VIEW_DEBUG
if (debugF)
{
printf("put_pixel_256 called with %d rows, debugrow %d\n",num_rows,debugrow);
debugrow+=num_rows;
}
else {
#endif
for (row = 0; row < num_rows; row++)
{
if (Ytotal <= (NewTotal + (1L << InflateBase)))
{
ptr0 = pixel_data[0][row];
if (Xratio != (1L << InflateBase))
{
for (col = 0; col < cinfo->image_width; col++)
{
DispBuf256[(col * InvXratio + (1L << (InflateBase - 1))) >> InflateBase] =
*ptr0;
ptr0++;
}
memcpy ((char *) lOffset, DispBuf256, BytesPerPixel * width);
} /* for col */
else
memcpy ((char *) lOffset, ptr0, BytesPerPixel * width);
lOffset += (long) bytesPerRow;
/*
PutVideoRow30H(NewTotal + YOffset, XOffset, width, DispBuf);
*/
NewTotal += (1L << InflateBase);
Ytotal += Yratio;
}
else
Ytotal -= (1L << InflateBase);
} /* for row */
#ifdef VIEW_DEBUG
}
#endif
}
METHODDEF void
put_pixel_rows (decompress_info_ptr cinfo, int num_rows,
JSAMPIMAGE pixel_data)
/* Write some rows of output data */
{
/* This example shows how you might write full-color RGB data (3
components) to an output file in which the data is stored 3 bytes per
pixel. */
JSAMPROW ptr0, ptr1, ptr2;
ulong *b0, *b1, *b2;
int col;
int row;
int newrow, mycol;
ulong temp0, temp1, temp2;
int endcol, scrcol;
char r, g, b;
register
WORD *pBuf; /* pointer to video row buffer */
WORD w0, w1, w2;
ulong rowfrac, colfrac;
/*
printf("got into put_pixel_rows\n");
*/
#ifdef VIEW_DEBUG
if (debugF)
{
printf("put_pixel_256 called with %d rows, debugrow %d\n",num_rows,debugrow);
debugrow+=num_rows;
}
else {
#endif
for (row = 0; row < num_rows; row++)
{
if (interpF)
{
ptr0 = pixel_data[0][row];
if (cinfo->out_color_space == CS_RGB)
{
ptr1 = pixel_data[1][row];
ptr2 = pixel_data[2][row];
}
else
ptr1 = ptr2 = ptr0;
b0 = Buffer0;
b1 = Buffer1;
b2 = Buffer2;
/*
printf("filrow: %d endrow: %d\n",filerow,endrow);
*/
/*
printf("starting as: %d\n",*ptr0);
*/
if (filerow == endrow)
{
endrow = ((scrrow + 2) * Yratio) >> InflateBase;
rowfrac = ((scrrow + 1) << InflateBase) - filerow * InvYratio;
for (col = 0; col < cinfo->image_width; col++)
{
*b0 += rowfrac * SRED;
*b1 += rowfrac * SGREEN;
*b2 += rowfrac * SBLUE;
b0++;
b1++;
b2++;
ptr0++;
ptr1++;
ptr2++;
}
/*
printf("after row interp: %u\n",*Buffer0);
*/
ptr0 = pixel_data[0][row];
if (cinfo->out_color_space == CS_RGB)
{
ptr1 = pixel_data[1][row];
ptr2 = pixel_data[2][row];
}
else
ptr1 = ptr2 = ptr0;
b0 = Buffer0;
b1 = Buffer1;
b2 = Buffer2;
rowfrac = InvYratio - rowfrac;
endcol = Xratio >> InflateBase;
scrcol = 0;
temp0 = temp1 = temp2 = 0;
for (col = 0; col < cinfo->image_width; col++)
{
if (col == endcol)
{
endcol = ((scrcol + 2) * Xratio) >> InflateBase;
colfrac = ((ulong) (scrcol + 1) << InflateBase) - (col * InvXratio);
temp0 += colfrac * ((*b0 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
temp1 += colfrac * ((*b1 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
temp2 += colfrac * ((*b2 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
/*
if (col==1) printf("after col frac: %u wih colfrac %u\n",temp0,colfrac);
*/
if (!ditherF)
DispBuf[scrcol] =
(((WORD) (ColorLUT[(temp0 + (1L << (ColorBase - 1))) >> ColorBase])) << 10 |
((WORD) (ColorLUT[(temp1 + (1L << (ColorBase - 1))) >> ColorBase])) << 5 |
(WORD) (ColorLUT[(temp2 + (1L << (ColorBase - 1))) >> ColorBase]));
else
{
Buffer0[scrcol] = ColorLUT256[(temp0 + (1L << (ColorBase - 1))) >> ColorBase];
Buffer1[scrcol] = ColorLUT256[(temp1 + (1L << (ColorBase - 1))) >> ColorBase];
Buffer2[scrcol] = ColorLUT256[(temp2 + (1L << (ColorBase - 1))) >> ColorBase];
}
colfrac = InvXratio - colfrac;
temp0 = colfrac * ((*b0 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
temp1 = colfrac * ((*b1 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
temp2 = colfrac * ((*b2 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
scrcol++;
}
else
{
temp0 += InvXratio * ((*b0 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
temp1 += InvXratio * ((*b1 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
temp2 += InvXratio * ((*b2 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
/*
if (!col) printf("after col add: %u\n",temp0);
*/
}
*b0++;
*b1++;
*b2++;
ptr0++;
ptr1++;
ptr2++;
}
/*
printf("after col interp: %u\n",*Buffer0);
*/
if (ditherF)
{
Dither (&DitherCtrl, Buffer0, Buffer0, scrrow % 2);
Dither (&DitherCtrl, Buffer1, Buffer1, scrrow % 2);
Dither (&DitherCtrl, Buffer2, Buffer2, scrrow % 2);
for (col = 0; col < width; col++)
DispBuf[col] = ((WORD) Buffer0[col] << 10) |
((WORD) Buffer1[col] << 5) |
((WORD) Buffer2[col]);
}
memcpy ((char *) lOffset, DispBuf, BytesPerPixel * width);
lOffset += (long) bytesPerRow;
scrrow++;
b0 = Buffer0;
b1 = Buffer1;
b2 = Buffer2;
ptr0 = pixel_data[0][row];
if (cinfo->out_color_space == CS_RGB)
{
ptr1 = pixel_data[1][row];
ptr2 = pixel_data[2][row];
}
else
ptr1 = ptr2 = ptr0;
for (col = 0; col < cinfo->image_width; col++)
{
*b0++ = rowfrac * SRED;
*b1++ = rowfrac * SGREEN;
*b2++ = rowfrac * SBLUE;
ptr0++;
ptr1++;
ptr2++;
}
}
else
{
for (col = 0; col < cinfo->image_width; col++)
{
*b0 += InvYratio * SRED;
*b1 += InvYratio * SGREEN;
*b2 += InvYratio * SBLUE;
b0++;
b1++;
b2++;
ptr0++;
ptr1++;
ptr2++;
}
/*
printf("after row add: %u\n",*Buffer0);
*/
}
filerow++;
}
else if (Ytotal <= (NewTotal + (1L << InflateBase)))
{
ptr0 = pixel_data[0][row];
if (cinfo->out_color_space == CS_RGB)
{
ptr1 = pixel_data[1][row];
ptr2 = pixel_data[2][row];
}
else
ptr1 = ptr2 = ptr0;
if (ditherF)
{
DitherChar (&DitherCtrl, ptr0, ptr0, (NewTotal >> InflateBase) % 2);
DitherChar (&DitherCtrl, ptr1, ptr1, (NewTotal >> InflateBase) % 2);
DitherChar (&DitherCtrl, ptr2, ptr2, (NewTotal >> InflateBase) % 2);
for (col = 0; col < cinfo->image_width; col++)
DispBuf[(col * InvXratio + (1L << (InflateBase - 1))) >> InflateBase] =
((WORD) ptr0[col] << 10) |
((WORD) ptr1[col] << 5) |
((WORD) ptr2[col]);
}
else
for (col = 0; col < cinfo->image_width; col++)
{
DispBuf[(col * InvXratio + (1L << (InflateBase - 1))) >> InflateBase] =
(((WORD) (ColorLUT[SRED])) << 10 |
((WORD) (ColorLUT[SGREEN])) << 5 |
(WORD) (ColorLUT[SBLUE]));
ptr0++;
ptr1++;
ptr2++;
} /* for */
/* calculate video page and offset */
memcpy ((char *) lOffset, DispBuf, BytesPerPixel * width);
lOffset += (long) bytesPerRow;
/*
PutVideoRow30H(NewTotal + YOffset, XOffset, width, DispBuf);
*/
NewTotal += (1L << InflateBase);
Ytotal += Yratio;
}
else
Ytotal -= (1L << InflateBase);
}
#ifdef VIEW_DEBUG
}
#endif
}
METHODDEF void
output_term (decompress_info_ptr cinfo)
/* Finish up at the end of the output */
{
/* This termination routine may not need to do anything. */
/* Note that the JPEG code will only call it during successful exit; */
/* if you want it called during error exit, you gotta do that yourself. */
DitherTerm (&DitherCtrl);
(*cinfo->emethods->free_all) ();
}
/*
* That's it for the routines that deal with writing the output image.
* Now we have overall control and parameter selection routines.
*/
/*
* This routine gets control after the JPEG file header has been read;
* at this point the image size and colorspace are known.
* The routine must determine what output routines are to be used, and make
* any decompression parameter changes that are desirable. For example,
* if it is found that the JPEG file is grayscale, you might want to do
* things differently than if it is color. You can also delay setting
* quantize_colors and associated options until this point.
*
* j_d_defaults initializes out_color_space to CS_RGB. If you want grayscale
* output you should set out_color_space to CS_GRAYSCALE. Note that you can
* force grayscale output from a color JPEG file (though not vice versa).
*/
METHODDEF void
d_ui_method_selection (decompress_info_ptr cinfo)
{
/* if grayscale input, force grayscale output; */
/* else leave the output colorspace as set by main routine. */
if (cinfo->jpeg_color_space == CS_GRAYSCALE)
cinfo->out_color_space = CS_GRAYSCALE;
/* select output routines */
cinfo->methods->output_init = output_init;
cinfo->methods->put_color_map = put_color_map;
if (hicolorF)
cinfo->methods->put_pixel_rows = put_pixel_rows;
else
cinfo->methods->put_pixel_rows = put_pixel_rows256;
if (ditherF)
cinfo->use_dithering = TRUE;
else cinfo->use_dithering = FALSE;
cinfo->methods->output_term = output_term;
}
/*
* OK, here is the main function that actually causes everything to happen.
* We assume here that the JPEG filename is supplied by the caller of this
* routine, and that all decompression parameters can be default values.
* The routine returns 1 if successful, 0 if not.
*/
GLOBAL int
read_JPEG_file (char *filename)
{
/* These three structs contain JPEG parameters and working data. They must
survive for the duration of parameter setup and one call to
jpeg_decompress; typically, making them local data in the calling
routine is the best strategy. */
struct decompress_info_struct cinfo;
struct decompress_methods_struct dc_methods;
struct external_methods_struct e_methods;
/* Select the input and output files. In this example we want to open the
input file before doing anything else, so that the setjmp() error
recovery below can assume the file is open. Note that cinfo.output_file
is only used if your output handling routines use it; otherwise, you can
just make it NULL. VERY IMPORTANT: use "b" option to fopen() if you are
on a machine that requires it in order to read binary files. */
if ((cinfo.input_file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, "can't open %s\n", filename);
return 0;
}
cinfo.output_file = NULL; /* if no actual output file involved */
/* Initialize the system-dependent method pointers. */
cinfo.methods = &dc_methods; /* links to method structs */
cinfo.emethods = &e_methods;
/* Here we supply our own error handler; compare to use of standard error
handler in the previous write_JPEG_file example. */
emethods = &e_methods; /* save struct addr for possible access */
e_methods.trace_level = 0;
e_methods.error_exit = error_exit; /* supply error-exit routine */
e_methods.trace_message = trace_message; /* supply trace-message
routine */
/* prepare setjmp context for possible exit from error_exit */
if (setjmp (setjmp_buffer))
{
/* If we get here, the JPEG code has signaled an error. Memory allocation
has already been cleaned up (see free_all call in error_exit), but we
need to close the input file before returning. You might also need to
close an output file, etc. */
fclose (cinfo.input_file);
return 0;
}
/* Here we use the standard memory manager provided with the JPEG code. In
some cases you might want to replace the memory manager, or at least the
system-dependent part of it, with your own code. */
jselmemmgr (&e_methods); /* select std memory allocation routines */
/* If the decompressor requires full-image buffers (for two-pass color
quantization or a noninterleaved JPEG file), it will create temporary
files for anything that doesn't fit within the maximum-memory setting.
You can change the default maximum-memory setting by changing
e_methods.max_memory_to_use after jselmemmgr returns. On some systems
you may also need to set up a signal handler to ensure that temporary
files are deleted if the program is interrupted. (This is most important
if you are on MS-DOS and use the jmemdos.c memory manager back end; it
will try to grab extended memory for temp files, and that space will NOT
be freed automatically.) See jcmain.c or jdmain.c for an example signal
handler. */
/* Here, set up the pointer to your own routine for post-header-reading
parameter selection. You could also initialize the pointers to the
output data handling routines here, if they are not dependent on the
image type. */
dc_methods.d_ui_method_selection = d_ui_method_selection;
/* Set up default decompression parameters. */
j_d_defaults (&cinfo, TRUE);
/* TRUE indicates that an input buffer should be allocated. In unusual
cases you may want to allocate the input buffer yourself; see jddeflts.c
for commentary. */
/* At this point you can modify the default parameters set by j_d_defaults
as needed; for example, you can request color quantization or force
grayscale output. See jdmain.c for examples of what you might change. */
if (!hicolorF)
{
cinfo.quantize_colors = TRUE;
if (twopassF)
cinfo.two_pass_quantize = TRUE;
else
cinfo.two_pass_quantize = FALSE;
}
if (blocksmoothF)
cinfo.do_block_smoothing = TRUE;
if (pixelsmoothF)
cinfo.do_pixel_smoothing = TRUE;
/* Set up to read a JFIF or baseline-JPEG file. */
/* This is the only JPEG file format currently supported. */
jselrjfif (&cinfo);
/* Here we go! */
jpeg_decompress (&cinfo);
/* That's it, son. Nothin' else to do, except close files. */
/* Here we assume only the input file need be closed. */
fclose (cinfo.input_file);
return 1; /* indicate success */
/* Note: if you want to decompress more than one image, we recommend you
repeat this whole routine. You MUST repeat the j_d_defaults()/alter
parameters/jpeg_decompress() sequence, as some data structures allocated
in j_d_defaults are freed upon exit from jpeg_decompress. */
}
void
read_TARGA_file (char *name)
{
struct compress_info_struct moh_cinfo;
struct decompress_info_struct moh_dcinfo;
struct compress_methods_struct moh_c_methods;
struct external_methods_struct moh_e_methods;
JSAMPARRAY pixel_row;
int i, j, k;
JSAMPIMAGE pixel_rows;
/* note the similarities here and read_JPEG_file */
/* ## clearly needs modularization */
moh_cinfo.methods = &moh_c_methods;
moh_cinfo.emethods = &moh_e_methods;
jselerror (&moh_e_methods); /* error/trace message routines */
jselmemmgr (&moh_e_methods); /* memory allocation routines */
if ((moh_cinfo.input_file = fopen (name, "rb")) == NULL)
{
fprintf (stderr, "Can't open %s\n", name);
exit (EXIT_FAILURE);
}
jselrtarga (&moh_cinfo);
moh_cinfo.total_passes = 0;
(*moh_cinfo.methods->input_init) (&moh_cinfo);
/* now to copy the info into a *de*compress info struct, */
/* as put_pixel_rows & output_init require that */
/* ## I dislike this hack */
moh_dcinfo.image_width = moh_cinfo.image_width;
moh_dcinfo.image_height = moh_cinfo.image_height;
moh_dcinfo.methods = moh_cinfo.methods;
moh_dcinfo.emethods = moh_cinfo.emethods;
moh_dcinfo.total_passes = moh_cinfo.total_passes;
moh_dcinfo.out_color_space = CS_RGB;
/* allolcate space for one row of data */
pixel_rows = (JSAMPIMAGE) (*moh_cinfo.emethods->alloc_small)
(3 * SIZEOF (JSAMPARRAY));
pixel_rows[0] = (JSAMPARRAY) (*moh_cinfo.emethods->alloc_small)
(MAXROWREAD * SIZEOF (JSAMPROW));
pixel_rows[1] = (JSAMPARRAY) (*moh_cinfo.emethods->alloc_small)
(MAXROWREAD * SIZEOF (JSAMPROW));
pixel_rows[2] = (JSAMPARRAY) (*moh_cinfo.emethods->alloc_small)
(MAXROWREAD * SIZEOF (JSAMPROW));
for (i = 0; i < 3; i++)
{
for (j = 0; j < MAXROWREAD; j++)
pixel_rows[i][j] = (JSAMPROW)
(*moh_cinfo.emethods->alloc_small) (moh_cinfo.image_width * sizeof (JSAMPLE));
}
pixel_row = (JSAMPARRAY) (*moh_cinfo.emethods->alloc_small)
(3 /* moh_cinfo.num_components */ * SIZEOF (JSAMPROW));
for (i = 0; i < 3 /* moh_cinfo.num_components */ ; i++)
pixel_row[i] = (JSAMPROW) (*moh_cinfo.emethods->alloc_small)
(moh_cinfo.image_width * sizeof (JSAMPLE));
/*
pixel_row=(JSAMPIMAGE) malloc(3 *sizeof(JSAMPARRAY));
for(i=0;i<3;i++)
pixel_row[i]=(JSAMPROW) malloc(sizeof(JSAMPLE)*moh_cinfo.image_width);
*/
output_init (&moh_dcinfo);
for (i = moh_cinfo.image_height; i;)
{
k = MIN (i, MAXROWREAD);
i -= k;
for (j = 0; j < k; j++)
{
pixel_row[0] = pixel_rows[0][j];
pixel_row[1] = pixel_rows[1][j];
pixel_row[2] = pixel_rows[2][j];
(*moh_cinfo.methods->get_input_row) (&moh_cinfo, pixel_row);
}
put_pixel_rows (&moh_dcinfo, k, pixel_rows);
}
/*now to free things */
(*moh_cinfo.emethods->free_all) ();
fclose (moh_cinfo.input_file);
}
void
read_GIF_file (char *name)
{
struct compress_info_struct moh_cinfo;
struct decompress_info_struct moh_dcinfo;
struct compress_methods_struct moh_c_methods;
struct external_methods_struct moh_e_methods;
JSAMPIMAGE pixel_row;
JSAMPIMAGE pixel_rows;
int i, j, k;
int temphicolor, tempdither;
temphicolor = hicolorF;
tempdither = ditherF;
hicolorF = 0;
ditherF = 0;
/* note the similarities here and read_JPEG_file */
/* ## clearly needs modularization */
moh_cinfo.methods = &moh_c_methods;
moh_cinfo.emethods = &moh_e_methods;
jselerror (&moh_e_methods); /* error/trace message routines */
jselmemmgr (&moh_e_methods); /* memory allocation routines */
if ((moh_cinfo.input_file = fopen (name, "rb")) == NULL)
{
fprintf (stderr, "Can't open %s\n", name);
exit (EXIT_FAILURE);
}
jselrgif (&moh_cinfo);
moh_cinfo.total_passes = 0;
(*moh_cinfo.methods->input_init) (&moh_cinfo);
/* now to copy the info into a *de*compress info struct, */
/* as put_pixel_rows & output_init require that */
/* ## I dislike this hack */
moh_dcinfo.image_width = moh_cinfo.image_width;
moh_dcinfo.image_height = moh_cinfo.image_height;
moh_dcinfo.methods = moh_cinfo.methods;
moh_dcinfo.emethods = moh_cinfo.emethods;
moh_dcinfo.total_passes = moh_cinfo.total_passes;
moh_dcinfo.out_color_space = CS_RGB;
/* allolcate space for one row of data */
pixel_row = (JSAMPIMAGE) (*moh_cinfo.emethods->alloc_small)
(1 * SIZEOF (JSAMPARRAY));
pixel_row[0] = (JSAMPARRAY) (*moh_cinfo.emethods->alloc_small)
(MAXROWREAD * SIZEOF (JSAMPROW));
pixel_row[0][0] = (JSAMPROW)
(*moh_cinfo.emethods->alloc_small) (moh_cinfo.image_width * sizeof (JSAMPLE));
output_init (&moh_dcinfo);
put_color_map (&moh_dcinfo, 256, gifcolormap);
for (i = moh_cinfo.image_height; i; i--)
{
(*moh_cinfo.methods->get_input_row) (&moh_cinfo, (JSAMPARRAY) pixel_row);
put_pixel_rows256 (&moh_dcinfo, 1, pixel_row);
}
/*now to free things */
(*moh_cinfo.emethods->free_all) ();
fclose (moh_cinfo.input_file);
hicolorF = temphicolor;
ditherF = tempdither;
}
void pauseorkey(int delay)
{
int keyhit;
keyhit=0;
if (delay<0) getch();
else while((!keyhit) && (delay>0))
{
sleep(1);
delay--;
keyhit=kbhit();
if (keyhit) getch();
}
}
void
Usage ()
{
fprintf (stderr, "Usage: hiview [options] file ...\n");
fprintf (stderr, " where the options are:\n");
fprintf (stderr, " -d toggle Floyd-Steinberg dithering, default is off\n");
fprintf (stderr, " -i toggle smooth interpolation when resizing image, default is on\n");
fprintf (stderr, " -g GIF format file\n");
fprintf (stderr, " -t TARGA format file\n");
fprintf (stderr, " -s <gamma> contrast stretch using exponent gamma\n");
fprintf (stderr, " gamma is a positive double precision number\n");
fprintf (stderr, " values are typically in the range 0.5 .. 1.5\n");
fprintf (stderr, " -q toggle one/two pass quantization, default is one\n");
fprintf (stderr, " -? this message\n");
fprintf (stderr, " -D Debug mode\n");
fprintf (stderr, " -T Display time of rendering\n");
fprintf (stderr, " -w Display files as a slide show, infinite delay.\n");
fprintf (stderr, " -W <delay> Display files as a slide show with <delay> seconds in between.\n");
fprintf (stderr, " <delay> must be an integer.");
fprintf (stderr, " Filenames may contain wildcards\n");
fprintf (stderr, "\n");
}
IMAGE_FORMATS
getformat (char *name)
{
char drive[MAXDRIVE];
char dir[MAXDIR];
char file[MAXFILE];
char ext[MAXEXT];
IMAGE_FORMATS type;
fnsplit (name, drive, dir, file, ext);
if (!strcmp (ext, ".JPG"))
type = FMT_JFIF;
else if (!strcmp (ext, ".GIF"))
type = FMT_GIF;
else if (!strcmp (ext, ".TGA"))
type = FMT_TARGA;
else
type = FMT_UNKNOWN;
return (type);
}
void
getfiles (char *path, IMAGE_FORMATS ex_type, int level)
{
struct ffblk tempfile;
int result;
char drive[MAXDRIVE];
char dir[MAXDIR];
char file[MAXFILE];
char ext[MAXEXT];
char newpath[500];
IMAGE_FORMATS type;
result = findfirst (path, &tempfile, 0 | FA_RDONLY | FA_DIREC);
type = ex_type;
while (result >= 0)
{
if (!(tempfile.ff_attrib & FA_DIREC))
{
fnsplit (path, drive, dir, file, ext);
strcpy (moh_files[totalfiles].name, drive);
strcat (moh_files[totalfiles].name, dir);
strcat (moh_files[totalfiles].name, tempfile.ff_name);
if (ex_type == FMT_UNKNOWN)
type = getformat (moh_files[totalfiles].name);
moh_files[totalfiles].type = type;
moh_files[totalfiles].selected = 0;
totalfiles++;
result = findnext (&tempfile);
}
else
{ /* find all *.jpg, gif, tga in directory */
fnsplit (path, drive, dir, file, ext);
strcpy (newpath, drive);
strcat (newpath, dir);
strcat (newpath, tempfile.ff_name);
result = findnext (&tempfile);
}
}
}
void
parse_command (int argc, char **argv)
{
struct ffblk tempfile;
int result, i, filespec;
IMAGE_FORMATS type;
char flag;
filespec = 0;
type = FMT_UNKNOWN;
for (i = 1; i < argc; i++)
{
if (*argv[i] == '-')
{
flag = *(argv[i] + 1);
switch (flag)
{
case 't':
type = FMT_TARGA;
break;
case 'g':
type = FMT_GIF;
break;
case 'j':
type = FMT_JFIF;
break;
case 'd':
ditherF = !ditherF;
break;
case 'i':
GinterpF = !GinterpF;
break;
case 's':
Gamma = atof (argv[++i]);
break;
case 'h':
hicolorF = !hicolorF;
break;
case 'b':
blocksmoothF = !blocksmoothF;
break;
case 'p':
pixelsmoothF = !pixelsmoothF;
break;
case 'q':
twopassF = !twopassF;
break;
case 'D':
debugF = 1;
break;
case 'T':
timeF = 1;
break;
case 'w':
slideF = 1;
slidedelay=-1;
break;
case 'W':
slideF = 1;
slidedelay = atoi (argv[++i]);
break;
case '?':
Usage ();
exit (0);
break;
}
}
else
{
filespec = 1;
getfiles (argv[i], type, 0);
}
}
if (!filespec)
{
getfiles ("*.jpg", FMT_JFIF, 1);
getfiles ("*.tga", FMT_TARGA, 1);
getfiles ("*.gif", FMT_GIF, 1);
}
}
void
draw_border ()
{
int i;
gotoxy (1, 1);
textbackground (BORDER_BCOLOR);
textcolor (BORDER_FCOLOR);
for (i = 1; i < SC_WIDTH - 1; i++)
cprintf (" ");
gotoxy (34, 1);
cprintf ("%s v.%s", PROGNAME,VERSION);
gotoxy (1, SC_HEIGHT);
for (i = 1; i < SC_WIDTH - 1; i++)
cprintf (" ");
gotoxy (1, SC_HEIGHT - 1);
textbackground (MESSAGE_BCOLOR);
textcolor (MESSAGE_FCOLOR);
cprintf ("%d Files.", totalfiles);
gotoxy (40, SC_HEIGHT - 1);
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("O");
textcolor (MESSAGE_FCOLOR);
cprintf ("ptions");
}
void
highlight (int fileoffset, int currentpos, int on)
{
int x, y, i, j;
int colheight;
char drive[MAXDRIVE];
char dir[MAXDIR];
char file[MAXFILE];
char ext[MAXEXT];
colheight = SC_HEIGHT - SC_HEADER - SC_FOOTER;
x = (SC_WIDTH - SC_COLS * SC_COL_WIDTH) / 2;
y = SC_HEADER + 1;
i = currentpos - fileoffset;
while (i >= colheight)
{
i -= colheight;
x += SC_COL_WIDTH;
}
y += i;
x -= 1;
gotoxy (x, y);
if (on)
{
textcolor (FILE_BCOLOR);
if (moh_files[currentpos].selected) textcolor(FILE_SELECT);
textbackground (FILE_FCOLOR);
}
else
{
textbackground (FILE_BCOLOR);
if (moh_files[currentpos].selected) textcolor(FILE_SELECT);
else textcolor (FILE_FCOLOR);
}
for (i = 0; i < SC_COL_WIDTH; i++)
cprintf (" ");
gotoxy (x, y);
fnsplit (moh_files[currentpos].name, drive, dir, file, ext);
cprintf (" %s", file);
gotoxy (x + 10, y);
cprintf ("%s ", ext);
textbackground (FILE_BCOLOR);
textcolor (FILE_FCOLOR);
}
void
print_files (int fileoffset, int currentpos)
{
int i, j, k;
int x, y, lastfile;
int onscreen;
char drive[MAXDRIVE];
char dir[MAXDIR];
char myfilename[50];
char ext[MAXEXT];
onscreen = (SC_HEIGHT - SC_HEADER - SC_FOOTER) * SC_COLS;
textbackground (FILE_BCOLOR);
textcolor (FILE_FCOLOR);
for (i = SC_HEADER + 1; i <= SC_HEIGHT - SC_FOOTER; i++)
{
gotoxy (1, i);
clreol ();
}
x = (SC_WIDTH - SC_COLS * SC_COL_WIDTH) / 2;
y = SC_HEADER + 1;
lastfile = MIN (totalfiles, onscreen + fileoffset);
for (i = fileoffset; i < lastfile; i++)
{
gotoxy (x, y);
fnsplit (moh_files[i].name, drive, dir, myfilename, ext);
if (moh_files[i].selected) textcolor(FILE_SELECT);
else textcolor(FILE_FCOLOR);
cprintf ("%s", myfilename);
gotoxy (x + 9, y);
cprintf ("%s", ext);
y++;
if (y > SC_HEIGHT - SC_FOOTER)
{
x += SC_COL_WIDTH;
y = SC_HEADER + 1;
}
}
highlight (fileoffset, currentpos, 1);
}
double
getdouble ()
{
double gamma;
scanf ("%lf", &gamma);
if (gamma<0) gamma=1;
return (gamma);
}
void
optionsmenu ()
{
int quitF = 0;
int c;
clrscr ();
gotoxy (1, SC_HEADER + 1);
textbackground (MESSAGE_BCOLOR);
textcolor (MESSAGE_HEADER);
cprintf ("Global Options: ");
gotoxy (1, SC_HEADER + 2);
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("H");
textcolor (MESSAGE_FCOLOR);
cprintf ("icolor: ");
if (nohicolor)
cprintf ("Not available.");
else if (hicolorF)
cprintf ("Used.");
else
cprintf ("Not used.");
gotoxy (1, SC_HEADER + 3);
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("B");
textcolor (MESSAGE_FCOLOR);
cprintf ("lock smoothing: ");
if (blocksmoothF)
cprintf ("Yes.");
else
cprintf ("No.");
gotoxy (1, SC_HEADER + 4);
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("P");
textcolor (MESSAGE_FCOLOR);
cprintf ("ixel smoothing: ");
if (pixelsmoothF)
cprintf ("Yes.");
else
cprintf ("No");
gotoxy (1, SC_HEADER + 5);
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("G");
textcolor (MESSAGE_FCOLOR);
cprintf ("amma: %0.2lf\n", Gamma);
gotoxy (1, SC_HEADER + 6);
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("D");
textcolor (MESSAGE_FCOLOR);
cprintf ("ithering: ");
if (ditherF)
cprintf ("Floyd-Steinberg.\n");
else
cprintf ("None.\n");
gotoxy (1, SC_HEADER + 8);
textcolor (MESSAGE_HEADER);
cprintf ("24->15 bit Options: ");
gotoxy (1, SC_HEADER + 9);
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("I");
textcolor (MESSAGE_FCOLOR);
cprintf ("nterpolation: ");
if (GinterpF)
cprintf ("Linear Averaging.\n");
else
cprintf ("None.\n");
gotoxy (1, SC_HEADER + 11);
textcolor (MESSAGE_HEADER);
cprintf ("24->8 bit Options: ");
gotoxy (1, SC_HEADER + 12);
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("Q");
textcolor (MESSAGE_FCOLOR);
cprintf ("uantization: ");
if (twopassF)
cprintf ("Two pass.");
else
cprintf ("One Pass.");
gotoxy (1, SC_HEADER + 14);
textcolor (MESSAGE_HEADER);
cprintf ("Slide Show Options: ");
gotoxy (1, SC_HEADER + 15);
textcolor (MESSAGE_FCOLOR);
cprintf ("De");
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("l");
textcolor (MESSAGE_FCOLOR);
cprintf ("ay: ");
if (slidedelay<0)
cprintf ("Infinite");
else
cprintf ("%d seconds.",slidedelay);
while (!quitF)
{
gotoxy (1, SC_HEIGHT - SC_FOOTER - 1);
clreol ();
cprintf ("Please enter your choice: ");
c = getxkey ();
switch (c)
{
case 'i':
case 'I':
GinterpF = !GinterpF;
gotoxy (1, SC_HEADER + 9);
clreol ();
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("I");
textcolor (MESSAGE_FCOLOR);
cprintf ("nterpolation: ");
if (GinterpF)
cprintf ("Linear Averaging.\n");
else
cprintf ("None.\n");
clreol ();
break;
case 'd':
case 'D':
ditherF = !ditherF;
gotoxy (1, SC_HEADER + 6);
clreol ();
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("D");
textcolor (MESSAGE_FCOLOR);
cprintf ("ithering: ");
if (ditherF)
cprintf ("Floyd-Steinberg.\n");
else
cprintf ("None.\n");
clreol ();
break;
case 'g':
case 'G':
gotoxy (1, SC_HEIGHT - SC_FOOTER - 1);
clreol ();
cprintf ("Please enter gamma: ");
Gamma = getdouble ();
/*
MakeColorLUT (ColorLUT, 0, 255, 0, 31, Gamma);
*/
MakeColorLUT (ColorLUT, 31, Gamma);
ColorLUT[256] = ColorLUT[255];/* to take care of rounding errors */
/*
MakeColorLUT (ColorLUT256, 0, 255, 0, 255, Gamma);
*/
MakeColorLUT (ColorLUT256, 255, Gamma);
ColorLUT256[256] = ColorLUT256[255];
gotoxy (1, SC_HEADER + 5);
clreol ();
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("G");
textcolor (MESSAGE_FCOLOR);
cprintf ("amma: %0.2lf\n", Gamma);
break;
case 'b':
case 'B':
blocksmoothF = !blocksmoothF;
gotoxy (1, SC_HEADER + 3);
clreol ();
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("B");
textcolor (MESSAGE_FCOLOR);
cprintf ("lock smoothing: ");
if (blocksmoothF)
cprintf ("Yes.");
else
cprintf ("No.");
break;
case 'p':
case 'P':
pixelsmoothF = !pixelsmoothF;
gotoxy (1, SC_HEADER + 4);
clreol ();
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("P");
textcolor (MESSAGE_FCOLOR);
cprintf ("ixel smoothing: ");
if (pixelsmoothF)
cprintf ("Yes.");
else
cprintf ("No");
break;
case 'q':
case 'Q':
twopassF = !twopassF;
gotoxy (1, SC_HEADER + 12);
clreol ();
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("Q");
textcolor (MESSAGE_FCOLOR);
cprintf ("uantization: ");
if (twopassF)
cprintf ("Two pass.");
else
cprintf ("One Pass.");
break;
case 'h':
case 'H':
if (!nohicolor)
{
hicolorF = !hicolorF;
gotoxy (1, SC_HEADER + 2);
clreol ();
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("H");
textcolor (MESSAGE_FCOLOR);
cprintf ("icolor: ");
if (hicolorF)
cprintf ("Used.");
else
cprintf ("Not used.");
}
break;
case 'l': case 'L':
gotoxy (1, SC_HEIGHT - SC_FOOTER - 1);
clreol ();
cprintf ("Please enter delay in seconds (negative number for infinite): ");
scanf("%d",&slidedelay);
gotoxy (1, SC_HEADER + 15);
clreol();
textcolor (MESSAGE_FCOLOR);
cprintf ("De");
textcolor (MESSAGE_HIGHLIGHT);
cprintf ("l");
textcolor (MESSAGE_FCOLOR);
cprintf ("ay: ");
if (slidedelay<0)
cprintf ("Infinite");
else
cprintf ("%d seconds.",slidedelay);
break;
case ESC:
case RETURN:
quitF = 1;
break;
}
} /* while */
}
void
userint ()
{
int quitF = 0;
int fileoffset = 0;
int currentpos = 0;
int onscreen;
int specialF;
int c;
int colheight;
int sec;
int usec;
int selected=0;
struct timeval tv;
struct timezone dummy;
int count;
colheight = SC_HEIGHT - SC_HEADER - SC_FOOTER;
onscreen = colheight * SC_COLS;
clrscr ();
draw_border ();
print_files (fileoffset, currentpos);
while (!quitF)
{
c = getxkey ();
switch (c)
{
case UP:
currentpos--;
if (currentpos < 0)
currentpos = 0;
else if (currentpos < fileoffset)
{
fileoffset--;
print_files (fileoffset, currentpos);
}
else
{
highlight (fileoffset, currentpos + 1, 0);
highlight (fileoffset, currentpos, 1);
}
break;
case DOWN:
currentpos++;
if (currentpos >= totalfiles)
currentpos = totalfiles - 1;
else if (currentpos > fileoffset + onscreen - 1)
{
fileoffset++;
print_files (fileoffset, currentpos);
}
else
{
highlight (fileoffset, currentpos - 1, 0);
highlight (fileoffset, currentpos, 1);
}
break;
case RIGHT:
highlight (fileoffset, currentpos, 0);
currentpos += colheight;
if (currentpos >= totalfiles)
currentpos = totalfiles - 1;
if (currentpos > fileoffset + onscreen - 1)
{
fileoffset += colheight;
print_files (fileoffset, currentpos);
}
else
{
highlight (fileoffset, currentpos, 1);
}
break;
case LEFT:
highlight (fileoffset, currentpos, 0);
currentpos -= colheight;
if (currentpos < 0)
currentpos = 0;
if (currentpos < fileoffset)
{
fileoffset -= colheight;
if (fileoffset < 0)
fileoffset = 0;
print_files (fileoffset, currentpos);
}
else
{
highlight (fileoffset, currentpos, 1);
}
break;
case 'o':
case 'O':
optionsmenu ();
clrscr ();
draw_border ();
print_files (fileoffset, currentpos);
break;
case ESC:
return;
break;
case ' ':
moh_files[currentpos].selected=!moh_files[currentpos].selected;
if (moh_files[currentpos].selected) selected++;
else selected--;
currentpos++;
if (currentpos >= totalfiles)
{
currentpos = totalfiles - 1;
highlight(fileoffset,currentpos,1);
}
else if (currentpos > fileoffset + onscreen - 1)
{
fileoffset++;
print_files (fileoffset, currentpos);
}
else
{
highlight (fileoffset, currentpos - 1, 0);
highlight (fileoffset, currentpos, 1);
}
break;
case RETURN:
if (timeF)
{
gettimeofday(&tv,&dummy);
sec=tv.tv_sec;
usec=tv.tv_usec/10000;
}
if (!selected) moh_files[currentpos].selected=1;
for(count=0;count<totalfiles;count++)
if (moh_files[count].selected)
{
switch (moh_files[count].type)
{
case FMT_JFIF:
read_JPEG_file (moh_files[count].name);
break;
case FMT_TARGA:
read_TARGA_file (moh_files[count].name);
break;
case FMT_GIF:
read_GIF_file (moh_files[count].name);
break;
}
if (timeF)
{
gettimeofday(&tv,&dummy);
sec=tv.tv_sec-sec;
usec=tv.tv_usec/10000-usec;
if (usec<0) {usec+=100; sec-=1;}
}
pauseorkey(slidedelay);
moh_files[count].selected=0;
}
selected=0;
GrSetMode (GR_80_25_text);
if (timeF)
{
printf("\n\n\n\t It took %d.%d seconds to render\n",sec,usec);
getch();
clrscr();
}
draw_border ();
print_files (fileoffset, currentpos);
break;
case 'q':
quitF = 1;
break;
}
} /* while */
}
main (int argc, char **argv)
{
char *fname;
IMAGE_FORMATS filetype;
int i, j, a;
timeF=0;
debugF = 0;
scaleF = 1;
sameaspectF = 1;
GinterpF = 1;
interpF = 1;
slideF=0;
Gamma = 1.0;
slidedelay=-1;
blocksmoothF = 0;
pixelsmoothF = 0;
twopassF = 1;
filetype = FMT_JFIF;
ditherF = 1;
if (debugF)
for (i = 0; i < argc; i++)
printf ("%s\n", argv[i]);
nohicolor = 1;
parse_command (argc, argv);
if (debugF)
{
printf ("parsed %d files\n", totalfiles);
for (i = 0; i < totalfiles; i++)
printf ("%s\n", moh_files[i].name);
getch ();
}
gppconio_init ();
if (totalfiles)
{
/*
MakeColorLUT (ColorLUT, 0, 255, 0, 31, Gamma);
*/
MakeColorLUT (ColorLUT, 31, Gamma);
ColorLUT[256] = ColorLUT[255];/* to take care of rounding errors */
/*
MakeColorLUT (ColorLUT256, 0, 255, 0, 255, Gamma);
*/
MakeColorLUT (ColorLUT256, 255, Gamma);
ColorLUT256[256] = ColorLUT256[255];
old_driversF=0;
GrGetDriverModes (&ttab, >ab);
F1024 = F800 = F640 = hi800F = hi640F = 0;
if (gtab!=NULL)
for (i = 0; gtab[i].width != 0; i++)
{
if (gtab[i].number_of_colors == 32768)
nohicolor = 0;
if (gtab[i].width == 1024 && gtab[i].height == 768 &&
gtab[i].number_of_colors == 256)
F1024 = 1;
if (gtab[i].width == 800 && gtab[i].height == 600 &&
gtab[i].number_of_colors == 256)
F800 = 1;
if (gtab[i].width == 640 && gtab[i].height == 480 &&
gtab[i].number_of_colors == 256)
F640 = 1;
if (gtab[i].width == 800 && gtab[i].height == 600 &&
gtab[i].number_of_colors == 32768)
hi800F = 1;
if (gtab[i].width == 640 && gtab[i].height == 480 &&
gtab[i].number_of_colors == 32768)
hi640F = 1;
}
else
{
old_driversF=1;
GrSetMode(GR_width_height_graphics,640,480);
if (GrSizeX()==640 && GrSizeY()==480) F640=1;
if (GrSizeX()==800 && GrSizeY()==600) F800=1;
if (GrSizeX()==1024 && GrSizeY()==768) F1024=1;
GrSetMode (GR_80_25_text);
}
if (F640==F1024==F800==hi800F==hi640F==0)
{
printf("Sorry, Video card not supported.\n");
exit(1);
}
if (nohicolor)
hicolorF = 0;
else if (hicolorF) hicolorF=0; else hicolorF=1;
if (hicolorF) ditherF=!ditherF;
if (slideF)
{
for(i=0;i<totalfiles;i++)
{
switch (moh_files[i].type)
{
case FMT_JFIF:
read_JPEG_file (moh_files[i].name);
break;
case FMT_TARGA:
read_TARGA_file (moh_files[i].name);
break;
case FMT_GIF:
read_GIF_file (moh_files[i].name);
break;
}
pauseorkey(slidedelay);
}
}
userint ();
GrSetMode (GR_80_25_text);
}
else printf("No files found");
return 0;
}
void
mr_prints (int x, int y, int attr, char *str)
{
while (*str)
{
if (*str == '\t')
x = (x / 8) * 8 + 8;
else if (*str == '\n')
y++;
else
ScreenPutChar (*(str++), attr, x++, y);
if (x >= 80)
{
y++;
x = 0;
}
}
}